前一篇解釋了實體變數與類別變數的差別,也提到物件的狀態與行為在程式裡面的對應關係,狀態(state)就是實體變數(instance variables),行為(behavior)則對應到方法(method),這篇就挑與方法相關的來挑戰吧!
What is the difference between class methods and instance methods?
類別方法與實體方法差異是什麼?
方法是Ruby當中讓物件去完成一些行為(動作),譬如以下舉的例子
def say_hi
puts "hi"
end
say_hi # => hi
在Ruby當中用def
開頭後面接方法的名字,以end
結尾,來定義一個方法,後來呼叫這個方法之後,就會執行方法內的動作,同時也會回傳最後一行執行的結果。
顧名思義,方法依造作用的對象不同而分成了實體方法及類別方法,實體可以使用的方法稱為實體方法,類別可以使用的方法為類別方法。以下面的例子來做範例。
class Human
def initialize(name)
@name = name
end
def say_my_name
puts "I'm #{@name}."
end
def self.say_hi
puts "hi from class method"
end
end
John = Human.new('John')
Mary = Human.new('瑪麗')
#實體方法 instance method
John.say_my_name # => I'm John.
Mary.say_my_name # => I'm 瑪麗.
Human.say_my_name # => 噴錯(NoMethodError)
#類別方法 class method
Human.say_hi # => hi from class method
首先定義了Human這個Class,以及產生John/Mary兩個實體,say_my_name
這個方法是屬於實體方法,是作用在John與Mary兩個實體上。如果用Human這個類別硬要呼叫的話,可是會出錯的。而類別方法是在def
後面用self
開頭來定義,像是後面定義的say_hi
就是屬於類別方法,class << self
裡面包方法來定義類別方法,上面的例子來改寫就會變成:
class << self
def say_hi
puts "hi from class method"
end
end
在Rails中,大家一定都不陌生下面這種寫法。
class UsersController < ApplicationController
def index
@users = User.all #撈出所有的user
end
end
all
方法是直接作用在User這個類別上,所以也是屬於類別方法。
實體方法與類別方法的差異為作用的對象不同,實體方法是作用在實體上,而類別方法是作用在類別上。在Ruby中定義的方式也不同,定義類別方法則需要以self
開頭或使用class << self
裡面再包方法,而實體方法則不用。